#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import threading


class Log(object):
    def __init__(self, is_ca_log, timestamp, content):
        self.is_ca_log = is_ca_log
        self.timestamp = timestamp
        self.content = content


class Node(object):
    def __init__(self, elem, ahead=None, next=None):
        self.ahead = ahead  # 表示上一个链接的链点
        self.elem = elem  # 表示对应的元素值
        self.next = next  # 表示下一个链接的链点


class Queue(object):
    def __init__(self):
        self.head = None  # 头部链点为 None
        self.rear = None  # 尾部链点为 None
        self.lock = threading.RLock()

    def is_empty(self):
        return self.head is None  # 判断队列是否为空

    def insert_node(self, rear, p):
        temp = rear
        while temp.ahead is not None and p.elem.timestamp < temp.elem.timestamp:
            temp = temp.ahead
        p.next = temp.next
        p.ahead = temp
        temp.next = p
        if p.next is not None:
            p.next.ahead = p

    def semaphore_release(self):
        log_semaphore.release()

    def enqueue(self, elem):
        """
        往队尾添加一个元素
        :param elem:
        :return:
        """
        self.lock.acquire()
        p = Node(elem)  # 初始化一个新的点
        if self.is_empty():
            self.head = p  # 队列头部为新的链点
            self.rear = p  # 队列尾部为新的链点
        else:
            if p.elem.timestamp < self.rear.elem.timestamp:
                # print(str(p.elem.timestamp) + "   " + str(self.rear.elem.timestamp))
                self.insert_node(self.rear, p)
            else:
                p.ahead = self.rear  # 这个新的点的前节点是当前的尾部
                self.rear.next = p  # 队列尾部的后继是这个新的点
                self.rear = p  # 然后让队列尾部指针指向这个新的点

        # log 缓存0.1s
        t = threading.Timer(0.1, self.semaphore_release)
        t.start()

        self.lock.release()

    def dequeue(self):
        """
        从队列头部删除一个元素，并返回这个值，类似于pop
        :return:
        """
        if self.is_empty():  # 判断队列是否为空
            pass
            # print('Queue_is_empty')  # 若队列为空，则退出 dequeue 操作
        else:
            self.lock.acquire()
            result = self.head.elem  # result为队列头部元素
            self.head = self.head.next  # 改变队列头部指针位置
            self.lock.release()
            return result  # 返回队列头部元素

    def peek(self):
        """
        查看队列的队头
        :return:
        """
        if self.is_empty():  # 判断队列是否为空
            print('NOT_FOUND')  # 为空则返回 NOT_FOUND
        else:
            return self.head.elem  # 返回队列头部元素


log_semaphore = threading.Semaphore(0)
log_queue = Queue()
log_queue.enqueue(Log(True, 1, "1\n"))
log_queue.enqueue(Log(True, 2, "2\n"))
log_queue.enqueue(Log(True, 3, "3-1\n"))
log_queue.enqueue(Log(True, 3, "3-2\n"))
log_queue.enqueue(Log(True, 4, "4\n"))
log_queue.enqueue(Log(True, 5, "5\n"))
log_queue.enqueue(Log(True, 3, "3-3\n"))
log_queue.enqueue(Log(True, 3, "3-4\n"))
log_queue.enqueue(Log(True, 3, "3-5\n"))
while True:
    log_semaphore.acquire()
    log = log_queue.dequeue()
    if log is not None:
        sys.stdout.write(str(log.timestamp) + "   "+log.content)
        sys.stdout.flush()
